package com.ican.strategy.impl;

import cn.hutool.core.lang.UUID;
import com.ican.enums.FilePathEnum;
import com.ican.exception.ServiceException;
import com.ican.strategy.UploadStrategy;
import com.ican.utils.FileUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 抽象上传模板
 *
 * @author ican
 */
@Slf4j
@Service
public abstract class AbstractUploadStrategyImpl implements UploadStrategy {
    @Value("${blog.file.max-size}")
    private Long maxFileSize;

    @Override
    public String uploadFile(MultipartFile file, String path) {
        if (file.getSize() > maxFileSize) {
            throw new ServiceException("文件超过1GB，上传失败");
        }
        String originalFilename = null;
        try {
            //  生成文件在服务器中的名字
            String realName = "";
            originalFilename = file.getOriginalFilename();
            String uuid = UUID.fastUUID().toString();
            if (FilePathEnum.AVATAR.getPath().equals(path)) {
                //  头像会将文件转换为blob格式，导致无法获取文件名
                realName = uuid + ".png";
            } else {
                String fileName = originalFilename.substring(0, originalFilename.lastIndexOf("."));
                //  获取文件扩展名
                String ext = FileUtils.getExtension(file);
                ext = ext.toLowerCase();  //  小写转换
                //  文件名加uuid组成服务器中存放的文件
                realName = fileName + "_" + uuid + "." + ext;
            }

            //  上传文件
            upload(path, realName, file.getInputStream());
            //  返回文件访问路径
            return getFileAccessUrl(path + realName);
        } catch (Exception e) {
            log.error(originalFilename + "文件上传失败，失败原因 -> {}", e.toString());
            throw new ServiceException("文件上传失败");
        }
    }

    /**
     * 判断文件是否存在
     *
     * @param filePath 文件路径
     * @return {@link Boolean}
     */
    public abstract Boolean exists(String filePath);

    /**
     * 上传
     *
     * @param path        路径
     * @param fileName    文件名
     * @param inputStream 输入流
     * @throws IOException io异常
     */
    public abstract void upload(String path, String fileName, InputStream inputStream) throws IOException;

    /**
     * 获取文件访问url
     *
     * @param filePath 文件路径
     * @return {@link String} 文件url
     */
    public abstract String getFileAccessUrl(String filePath);
}
